export default class Bluetooth {
	/* 设备平台信息 */
	private platform : string = uni.getSystemInfoSync().platform; // 运行的设备平台，如ios/android

	/* 单例模式管理的蓝牙实例 */
	private static instance : Bluetooth;

	/* 蓝牙服务与特征值的默认值 */
	private deviceId : null | string; // 已连接设备的ID
	private serviceId : null | string; // 蓝牙服务UUID
	private characteristicId : null | string; // 特定特征值的UUID
	private adapterAvailable : boolean; // 蓝牙适配器可用状态
	private adapterDiscovering : boolean; // 蓝牙适配器是否处于搜索状态
	private findDeviceList : UniApp.BluetoothDeviceInfo[]; // 已发现的蓝牙设备列表
	private connect : boolean; // 低功耗蓝牙连接状态
	private connecting : boolean; // 低功耗蓝牙连接中状态
	private characteristicsWrite : boolean; // 特征值是否可以写入

	/* 连接与特征值回调 */
	private adapterStateChangeCb : | null | ((available : boolean, discovering : boolean) => void); // 可用状态及搜索状态变更回调
	private adapterAvailableStateChagneCb : null | ((available : boolean) => void); // 可用状态变更回调
	private adapterDiscoveringStateChagneCb : | null | ((available : boolean) => void); // 搜索状态变更回调
	private createBLEConnectionFailCb : | null | ((hasHistoryDeviceConnection : boolean) => void); // 连接失败回调
	private connectionStateChangeCb : | null | ((deviceId : string, connected : boolean) => void); // 连接状态变更回调
	private bluetoothDeviceFoundCb : | null | ((device : UniApp.BluetoothDeviceInfo[]) => void); // 设备搜索回调
	// private bluetoothDeviceFoundFailCb : null | (() => void); // 设备搜索回调
	private characteristicValueChangeCb : | null | ((characteristicChangeValue : any) => void); // 特征值变化事件回调

	/**
	 *  私有构造函数，防止外部直接实例化
	 */
	private constructor() {
		if (Bluetooth.instance) {
			// 这里不能直接返回Singleton.instance，因为构造函数必须返回this
			throw new Error("不能使用new创建多个Bluetooth实例，请使用Bluetooth.getInstance()");
		}
		this.deviceId = null; // 蓝牙服务id
		this.serviceId = "000000FF-0000-1000-8000-00805F9B34FB"; // 蓝牙服务
		this.characteristicId = "0000FF01-0000-1000-8000-00805F9B34FB"; // 特定特征值的UUID
		this.adapterAvailable = false; // 蓝牙适配器可用状态
		this.adapterDiscovering = false; // 蓝牙适配器是否处于搜索状态
		this.findDeviceList = []; // 已发现的蓝牙设备
		this.connect = false; // 低功耗蓝牙连接状态
		this.connecting = false; // 低功耗蓝牙连接中状态
		this.characteristicsWrite = false; // 特征值是否可以写入

		/* ------------------------------------------------------------------------------------------------- 初始化回调函数 ------------------------------------------------------------------------------------------------- */
		this.adapterStateChangeCb = null; // 蓝牙适配器可用状态以及搜索状态变更回调
		this.adapterAvailableStateChagneCb = null; // 蓝牙适配器可用状态变更回调
		this.adapterDiscoveringStateChagneCb = null; // 蓝牙适配器搜索状态变更回调
		this.bluetoothDeviceFoundCb = null; // 蓝牙适配器搜索设备回调
		// this.bluetoothDeviceFoundFailCb = null; // 蓝牙适配器搜索设备失败回调
		this.connectionStateChangeCb = null; // 低功耗蓝牙连接状态变更监听
		this.createBLEConnectionFailCb = null; // 低功耗蓝牙连接失败回调
		this.characteristicValueChangeCb = null; // 低功耗蓝牙设备的特征值变化事件回调

		/* ------------------------------------------------------------------------------------------------- 初始化监听器 ------------------------------------------------------------------------------------------------- */
		this.onBluetoothAdapterStateChange(); // 初始化适配器可用状态变更回调监听
		this.onBluetoothDeviceFound(); // 初始化适配器搜索结果回调监听
		this.onBLEConnectionStateChange(); // 初始化低功耗蓝牙连接状态变更监听
		this.onBLECharacteristicValueChange(); // 监听低功耗蓝牙设备的特征值变化事件监听

	}

	/**
	 * 获取Bluetooth实例
	 * 该函数确保了蓝牙实例的懒加载和单例模式：
	 * - 如果蓝牙实例已存在，则直接解决Promise。
	 * - 如果蓝牙实例不存在，则创建一个新的蓝牙实例，并尝试初始化蓝牙适配器。
	 * - 初始化成功或失败都会解决Promise，并通过事件发射器通知蓝牙适配器的可用状态。
	 *
	 * @returns {Promise<Bluetooth>} 返回一个Promise，该Promise解析为Bluetooth实例。
	 */
	public static getInstance() : Promise<Bluetooth> {
		return new Promise((resolve, reject) => {
			if (Bluetooth.instance) {
				// 如果已有蓝牙实例，则直接返回该实例
				resolve(Bluetooth.instance);
			} else {
				// 创建一个新的蓝牙实例
				Bluetooth.instance = new Bluetooth();
				// 尝试初始化蓝牙适配器
				uni.openBluetoothAdapter({
					complete: (res) => {
						// 根据初始化结果设置蓝牙适配器的可用状态
						if (res.errMsg === "openBluetoothAdapter:ok") {
							Bluetooth.instance.adapterAvailable = true;
							Bluetooth.instance.adapterDiscovering = false;
						} else {
							Bluetooth.instance.adapterAvailable = false;
							Bluetooth.instance.adapterDiscovering = false;
							uni.$emit("BluetoothAdapterAvailable", false);
						}
						// console.log("初始化蓝牙适配器成功");
						// 初始化完成后返回蓝牙实例
						return resolve(Bluetooth.instance);
					},
				});
			}
		});
	}

	/**
	 * 获取蓝牙实例的属性
	 */
	public getBluetoothInstanceInfo() {
		return {
			deviceId: this.deviceId, // 蓝牙服务id
			serviceId: this.serviceId, // 蓝牙服务id
			characteristicId: this.characteristicId, // 特定特征值的UUID
			adapterAvailable: this.adapterAvailable, // 蓝牙适配器可用状态
			adapterDiscovering: this.adapterDiscovering, // 蓝牙适配器是否处于搜索状态
			findDeviceList: this.findDeviceList, // 已发现的蓝牙设备
			connect: this.connect, // 低功耗蓝牙连接状态
			connecting: this.connecting, // 低功耗蓝牙连接中状态
			characteristicsWrite: this.characteristicsWrite, // 特征值是否可以写入
		};
	}

	/**
	 * 开始搜寻附近的蓝牙设备。
	 * @param {string[]} services 要搜索的蓝牙服务UUID列表。
	 */
	public startBluetoothDevicesDiscovery(services : Array<string> = []) : Promise<boolean> {
		if (!this.adapterAvailable) {
			// console.log("蓝牙适配器不可用")
			return Promise.resolve(false)

		}
		if (this.adapterDiscovering) {
			// console.log('蓝牙设备搜索中')
			return Promise.resolve(false)
		}
		return new Promise((resolve, reject) => {
			uni.startBluetoothDevicesDiscovery({
				allowDuplicatesKey: true, // 是否允许重复上报同一设备。如果允许重复上报，则 uni.onBlueToothDeviceFound 方法会多次上报同一设备，但是 RSSI 值会有不同。
				interval: 0, // 上报设备的间隔。0 表示找到新设备立即上报，其他数值根据传入的间隔上报。
				services,	// 要搜索的蓝牙设备主 service 的 uuid 列表
				success: () => {
					// console.log("开始搜寻附近的蓝牙设备")
					maskViewShowLoading({
						title: "搜索蓝牙设备",
					})
					this.adapterDiscovering = true;
					resolve(true)
				},
				fail: (err) => {
					// console.log("搜索失败", err);
					this.adapterDiscovering = false;
					reject(false)
				}
			})
		})
	}

	/**
	 * 连接至低功耗蓝牙设备。	 
	 * @param {UniApp.BluetoothDeviceInfo} device 要连接的蓝牙设备信息对象。
	 * @param {boolean} [hasHistoryDevice=false] 表示该设备是否为历史已连接过的设备，默认为false。
	 * @returns {Promise<void>} 返回一个Promise，当连接操作完成（不论成功还是失败）时解析。
	 */
	public connectDevice(device : UniApp.BluetoothDeviceInfo, hasHistoryDevice : boolean = false) : Promise<boolean> {
		if (this.connect) {
			console.error('蓝牙已连接');
			return Promise.resolve(true)
		}
		if (this.connecting) {
			console.error('蓝牙连接中,不允许重复发起连接');
			return Promise.reject(false)
		}
		this.connecting = true;

		return new Promise((resolve, reject) => {
			maskViewShowLoading({
				title: hasHistoryDevice ? "连接历史设备" : "设备连接中",
			})
			uni.createBLEConnection({
				deviceId: device.deviceId,	// 连接的设备ID
				timeout: 1500,				// 超时时间(京东小程序不支持)，单位ms，不填表示不会超时
				success: () => {
					if (this.adapterDiscovering) {		// 停止搜索蓝牙
						uni.stopBluetoothDevicesDiscovery()
					}
					this.deviceId = device.deviceId;
					uni.setStorageSync('historyBluetoothDevice', device);	// 写入缓存
					uni.showToast({
						title: "蓝牙设备连接成功",
						mark: true,
						position: "bottom"
					})
					console.log('蓝牙连接成功')
					if (this.platform === "android") {
						this.setAndroidBLEMTU(this.deviceId)
					}
					this.initBLEDeviceCharacteristics(this.deviceId, this.serviceId, this.characteristicId);
					resolve(true)
				},
				fail: (err) => {
					uni.$emit("BluetoothConnectionFail", hasHistoryDevice)
					if (this.createBLEConnectionFailCb) {
						this.createBLEConnectionFailCb(hasHistoryDevice)
					}
					reject(false)
				},
				complete: () => {
					this.connecting = false;
					maskViewHideLoading()
				}

			})
		})
	}

	/**
	 * 设置Android设备的蓝牙最大传输单元(MTU)。
	 * MTU决定了单次蓝牙通信中能传输的最大数据量，增大MTU可以提高数据传输效率。
	 * @param {string} deviceId - 要设置MTU的蓝牙设备ID。
	 * @param {number} [mtu=512] - 指定的MTU大小，默认为512字节。
	 * @returns {Promise<any>} - 返回一个Promise，当MTU设置操作完成时解析，无论成功或失败。
	 */
	public setAndroidBLEMTU(deviceId : string, mtu : number = 512) : Promise<any> {
		return new Promise((resolve, reject) => {
			uni.setBLEMTU({
				deviceId,
				mtu: mtu,
				success: (res) => {
					// console.log('设置蓝牙最大传输单元,成功', res);
					resolve(res);
				},
				fail: (err) => {
					// console.log('设置蓝牙最大传输单元失败', err);
					reject(err);
				}
			})
		})
	}

	/**
	 * 获取蓝牙设备特定服务中的所有特征值。
	 * @param {string} deviceId 蓝牙设备ID。
	 * @param {string} serviceId 蓝牙服务UUID
	 * @returns 特征值获取成功的Promise。
	 */
	public getBLEDeviceCharacteristics(deviceId : string, serviceId : string) : Promise<UniApp.GetBLEDeviceCharacteristicsSuccess> {
		return new Promise((resolve, reject) => {
			setTimeout(() => {
				uni.getBLEDeviceCharacteristics({
					deviceId,
					serviceId,
					success: (res) => {
						resolve(res);
					}, fail: (err) => {
						reject(err);
					}
				})
			}, 2000)

		})
	}
	/**
	 * 从低功耗蓝牙设备的特征值中读取二进制数据。
	 * 注意：必须设备的特征值支持 read 才可以成功调用。
	 *
	 * @param {string} deviceId 蓝牙设备ID.
	 * @param {string} serviceId 蓝牙服务UUID
	 * @param {string} characteristicId 特征值ID，默认为类内定义的特征值ID.
	 * @returns {Promise<UniApp.ReadBLECharacteristicValueSuccess>} 读取操作成功的Promise，包含读取到的特征值数据.
	 */
	public readBLECharacteristicValue(deviceId : string, serviceId : string, characteristicId : string) : Promise<UniApp.ReadBLECharacteristicValueSuccess> {
		return new Promise((resolve, reject) => {
			uni.readBLECharacteristicValue({
				deviceId,
				serviceId,
				characteristicId,
				success(res) {
					// console.log('开启读取特征值成功', res);
					resolve(res);
				},
				fail(err) {
					// console.log('开启读取特征值失败', err);
					reject(err);
				}
			});
		})
	}

	/**
	 * 监听低功耗蓝牙设备的特征值变化，启用或停用特征值变化通知。
	 *
	 * @param {string} deviceId 蓝牙设备ID.
	 * @param {string} serviceId 服务ID.
	 * @param {string} characteristicId 特征值ID.
	 * @returns {Promise<void>} 操作完成的Promise，无返回数据.
	 */
	public notifyBLECharacteristicValueChange(deviceId : string, serviceId ?: string, characteristicId ?: string) : Promise<UniApp.StopBluetoothDevicesDiscoverySuccess> {
		if (this.serviceId) {
			serviceId = this.serviceId
		}
		if (this.characteristicId) {
			characteristicId = this.characteristicId
		}

		return new Promise((resolve, reject) => {
			uni.notifyBLECharacteristicValueChange({
				deviceId,
				serviceId,
				characteristicId,
				state: true, // 启用 notify 功能
				success: (res) => {
					// console.log('启用notify成功', res);
					resolve(res);
				},
				fail: (err) => {
					reject(err);
				}
			})
		})
	}

	/**
	 * 初始化指定服务下的指定特征值的监听
	 * @param {string} deviceId - 蓝牙设备ID。
	 * @param {string} serviceId - 蓝牙服务UUID。
	 * @param {string} characteristicId - 蓝牙服务中特征值ID。
	 */
	public async initBLEDeviceCharacteristics(deviceId : string, serviceId : string, characteristicId : string) {
		try {
			const res = await this.getBLEDeviceCharacteristics(deviceId, serviceId);
			for (let i = 0; i < res.characteristics.length; i++) {
				let item = res.characteristics[i];
				if (item.uuid.indexOf(characteristicId) == -1) {
					return
				}
				if (item.properties.write) {
					this.characteristicsWrite = true;
					// console.log("当前的特征值可以写入状态:",this.characteristicsWrite)
				}

				if (item.properties.read) {
					try {
						await this.readBLECharacteristicValue(deviceId, serviceId, characteristicId)
						// console.log('开启读取特征值成功');
					} catch (err) {
						console.error('开启读取特征值失败', err);
					}
				}


				if (item.properties.notify || item.properties.indicate) {
					try {
						await this.notifyBLECharacteristicValueChange(deviceId, serviceId, characteristicId)
						// console.log('启用notify成功', res);
					} catch (err) {
						console.error('启用notify失败', err);
					}
				}


			}
		} catch (err) {
			console.log('获取特征值失败', err)
		}

	}

	/**
	 * 向蓝牙设备的特征值写入二进制数据。
	 * @param {string} value 要写入的数据。
	 * @param {string} deviceId 蓝牙设备ID。
	 * @param {string} serviceId  蓝牙服务ID。
	 * @param {string} characteristicId 蓝牙服务特征值ID。
	 * @returns  @returns {Promise<UniApp.ReadBLECharacteristicValueSuccess>} 写入操作成功的Promise。
	 */
	writeBLECharacteristicValue(value : string) : Promise<UniApp.StopBluetoothDevicesDiscoverySuccess> {
		return new Promise((resolve, reject) => {
			uni.writeBLECharacteristicValue({
				deviceId: this.deviceId,
				serviceId: this.serviceId,
				characteristicId: this.characteristicId,
				value: Bluetooth.hex2ArrayBuffer(value),
				success(res) {
					console.log("写入蓝牙数据成功")
					resolve(res);
				},
				fail(err) {
					console.log("写入蓝牙数据失败", err)
					reject(err);
				}
			})
		})
	}


	/* ------------------------------------------------------------------------------------------------------------------------ 蓝牙相关的监听初始化 ------------------------------------------------------------------------------------------------------------------------ */

	/**
	 * 设置蓝牙适配器状态变化的监听事件。
	 * 当蓝牙适配器的可用性和搜索状态发生变化时，触发相应的回调函数。
	 */
	onBluetoothAdapterStateChange() {
		uni.onBluetoothAdapterStateChange(({ available, discovering }) => {
			if (this.adapterStateChangeCb) {
				this.adapterStateChangeCb(available, discovering);
			}
			if (this.adapterAvailable != available) {
				this.adapterAvailable = available;
				uni.$emit("BluetoothAdapterAvailable", available);
				if (this.adapterAvailableStateChagneCb) {
					this.adapterAvailableStateChagneCb(available);
				}
			}
			if (this.adapterDiscovering != discovering) {
				this.adapterDiscovering = discovering;
				uni.$emit("BluetoothAdapterDiscovering", discovering);
				if (this.adapterDiscoveringStateChagneCb) {
					this.adapterDiscoveringStateChagneCb(discovering);
				}
			}
		})
	}

	/**
	 * 监听低功耗蓝牙连接状态变化事件。
	 * 当与低功耗蓝牙设备的连接状态发生改变时，触发回调。
	 */
	onBluetoothDeviceFound() {
		uni.onBluetoothDeviceFound((res) => {
			res.devices.forEach((device) => {
				if (this.serviceId) {
					// 找到指定服务ID的设备
					const idx = device.advertisServiceUUIDs.findIndex((serviceUUID : string) => {
						return serviceUUID === this.serviceId
					})
					if (idx != -1) {
						// console.log("发现了指定了服务ID，自动连接", device)
						this.connectDevice(device)
					}
				} else {
					// 添加到已发现的设备列表中
					const idx = this.findDeviceList.findIndex(deviceListItem => {
						return device.deviceId === deviceListItem.deviceId
					})
					if (idx === -1) {
						this.findDeviceList.push(device)
					} else {
						const oldDevice = {
							...this.findDeviceList[idx],
						}
						this.findDeviceList[idx] = {
							...oldDevice,
							RSSI: device.RSSI
						}
					}
				}
			});

			// 触发设备搜索回调
			uni.$emit('BluetoothDeviceFound', res.devices)
			if (this.bluetoothDeviceFoundCb) {
				this.bluetoothDeviceFoundCb(res.devices);
			}
		})
	}

	/**
	 * 监听低功耗蓝牙连接状态变化事件。
	 * 当与低功耗蓝牙设备的连接状态发生改变时，触发回调。
	 */
	onBLEConnectionStateChange() {
		uni.onBLEConnectionStateChange(({ deviceId, connected }) => {
			// 更新连接状态
			this.connect = connected;
			if (!connected) {		// 断开连接处理
				this.deviceId = null;
				// this.serviceId=null;	// 如果指定服务ID，请注释
				// this.characteristicId=null; // 如果指定指定特征值ID，请注释
				this.connecting = false;

				this.characteristicsWrite = false;
			}
			uni.$emit('BluetoothConnectionState', connected)
			// 触发回调
			if (this.connectionStateChangeCb) {
				this.connectionStateChangeCb(deviceId, connected)
			}
		})
	}

	/**
	 * 监听低功耗蓝牙设备的特征值变化事件。
	 * 须先启用notifyBLECharacteristicValueChange后才能接收到characteristicValueChange事件。
	 */
	onBLECharacteristicValueChange() {
		uni.onBLECharacteristicValueChange((characteristic) => {
			const res = {
				...characteristic,
				valueString: Bluetooth.ArrayBuffer2hex(characteristic.value)
			}
			console.log('低功耗蓝牙设备的特征值变化回调', res)
			uni.$emit("characteristicValueChange", res)
			if (this.characteristicValueChangeCb) {
				this.characteristicValueChangeCb(res);
			}
		})
	}

	/* ------------------------------------------------------------------------------------------------------------------------ 回调函数赋值修改 ------------------------------------------------------------------------------------------------------------------------ */


	/**
	 * 设置-蓝牙适配器可用状态以及搜索状态变化事件的回调函数。
	 * 当蓝牙适配器的可用性或搜索状态发生变化时，将调用此回调。
	 *
	 * @param {null | ((available : boolean, discovering : boolean) => void)} cb - 回调函数，接收两个参数：
	 *   - available {boolean}：表示蓝牙适配器是否可用。
	 *   - discovering {boolean}：表示蓝牙适配器是否正在搜索设备。
	 *   如果不希望设置回调，可以传入null。
	 */
	setAdapterStateChangeCb(cb : (null | ((available : boolean, discovering : boolean) => void)) = null) : void {
		this.adapterStateChangeCb = cb;
	}
	/**
	 * 设置-蓝牙适配器可用状态变化的事件回调函数。
	 * 当蓝牙适配器的可用状态发生改变时，将调用此回调。
	 *
	 * @param {null | ((available : boolean) => void)} cb - 回调函数，接收一个参数：
	 *   - available {boolean}：表示蓝牙适配器是否可用。
	 *   如果不希望设置回调，可以传入null。
	 */
	setAdapterAvailableStateChagneCb(cb : (null | ((available : boolean) => void))) {
		this.adapterAvailableStateChagneCb = cb;
	}

	/**
	 * 设置-蓝牙适配器搜索状态变化的事件回调函数。
	 * 当蓝牙适配器的搜索状态（是否在搜索设备）发生改变时，将调用此回调。
	 *
	 * @param {null | ((discovering : boolean) => void)} cb - 回调函数，接收一个参数：
	 *   - discovering {boolean}：表示蓝牙适配器是否正在搜索设备。
	 *   如果不希望设置回调，可以传入null。
	 */
	setAdapterDiscoveringStateChagneCb(cb : (null | ((discovering : boolean) => void)) = null) : void {
		this.adapterDiscoveringStateChagneCb = cb;
	}


	/**
	 * 设置-低功耗蓝牙连接失败的回调函数
	 * @param {null | ((hasHistoryDeviceConnection : boolean) => void)} cb - 回调函数，接收一个参数：
	 *   - hasHistoryDeviceConnection {boolean}：表示是否是来自历史设备尝试连接失败。
	 */
	setCreateBLEConnectionFailCb(cb : (null | ((hasHistoryDeviceConnection : boolean) => void)) = null) : void {
		this.createBLEConnectionFailCb = cb;
	}

	/**
	 * 设置-蓝牙设备搜索结果的回调函数。
	 * 当搜索到新的蓝牙设备时，将调用此回调。
	 *
	 * @param {null | ((device : UniApp.BluetoothDeviceInfo[]) => void)} cb - 回调函数，接收一个参数：
	 *   - device {UniApp.BluetoothDeviceInfo[]}：表示搜索到的蓝牙设备信息数组。
	 *   如果不希望设置回调，可以传入null。
	 */
	setBluetoothDeviceFoundCbB(cb : (null | ((device : UniApp.BluetoothDeviceInfo[]) => void)) = null) : void {
		this.bluetoothDeviceFoundCb = cb;
	}


	/**
	 * 设置-低功耗蓝牙连接状态变化的事件回调函数。
	 * 当与低功耗蓝牙设备的连接状态发生改变时，将调用此回调。
	 *
	 * @param {null | ((deviceId : string, connected : boolean) => void)} cb - 回调函数，接收两个参数：
	 *   - deviceId {string}：设备的ID。
	 *   - connected {boolean}：表示设备是否已连接。
	 *   如果不希望设置回调，可以传入null。
	 */
	setBLEConnectionStateChangeCb(cb : (null | ((deviceId : string, connected : boolean) => void)) = null) : void {
		this.connectionStateChangeCb = cb;
	}

	/**
	 * 设置-低功耗蓝牙搜索失败时候的回调函数
	 */
	// setBluetoothDeviceFoundFailCb(cb : (null | (() => void)) = null) : void {
	// 	this.bluetoothDeviceFoundFailCb = cb;
	// }

	/**
	 * 设置-低功耗蓝牙设备的特征值变化事件的回调函数。
	 * 当低功耗蓝牙设备的特征值发生变化时，将调用此回调。
	 * @param {null | ((characteristicChangeValue : any) => void)} cb - 回调函数，接收一个参数：
	 *   - characteristicChangeValue {any}：表示特征值变化事件。
	 */
	setCharacteristicValueChangeCb(cb : (null | ((characteristicChangeValue : any) => void)) = null) {
		this.characteristicValueChangeCb = cb;
	}



	/* ------------------------------------------------------------------------------------------------------------------------ 公共函数 ------------------------------------------------------------------------------------------------------------------------ */

	// ArrayBuffer转16进度字符串示例
	static ArrayBuffer2hex(buffer : Array<any>) : string {
		const hexArr = Array.prototype.map.call(
			new Uint8Array(buffer),
			function (bit : number) {
				return ('00' + bit.toString(16)).slice(-2)
			}
		)
		return hexArr.join('')
	}

	// 16进制字符串转ArrayBuffer
	static hex2ArrayBuffer(hexString : string) : Uint8Array {
		// 移除可能的前导 "0x"
		hexString = hexString.replace(/^0x/i, '');
		// 确保字符串长度是偶数，如果不是则前置补0
		if (hexString.length % 2 !== 0) {
			hexString = '0' + hexString;
		}
		// 将每两个字符一组转换为其对应的字节，并组合成Uint8Array
		const byteArray = new Uint8Array(hexString.match(/.{1,2}/g)?.map(byte => parseInt(byte, 16)) ?? []);

		return byteArray;
	}
}



const maskView = new plus.nativeObj.View("maskView", { // 给遮罩层一个唯一标识
	position: "absolute", // 设置为绝对定位
	top: '0', // 调整顶部距离，如果要遮挡整个页面包括tabbar，可能需要计算屏幕高度减去tabbar的高度
	left: '0',
	width: "100%", // 宽度充满屏幕
	height: "100%", // 高度充满屏幕，如果只想遮挡tabbar，可以调整此值为tabbar的高度
	backgroundColor: "rgba(0,0,0,0)", // 透明遮罩背景
});

function maskViewShowLoading(options : UniApp.ShowLoadingOptions) {
	maskView.show();
	uni.showLoading({ ...options, mask: true })
}

function maskViewHideLoading() {
	maskView.hide();
	uni.hideLoading()
}

function maskViewShowToast(toastOptions : UniApp.ShowToastOptions) {
	maskView.show();
	uni.showToast({
		...toastOptions,
		mask: true,
		complete: (res) => {
			toastOptions.complete(res);
			maskView.hide();
		}
	})
}